//this map use qt QMap and  inhert from GMap
//andycai_sc implement 2011-05-25

#ifndef GQTSTANDMAP_H
#define GQTSTANDMAP_H

#include "GTpl/IGMap.h"
#include <QMap>

template<typename Key, typename Value>
class GStandMap : public GMap<Key, Value>
{
public:
    GStandMap() {}
    virtual ~GStandMap() {}

    typename GMap<Key, Value>::IterPtr insert(const Key& key, const Value& value);
    int erase(const Key& key);
    void erase(typename GMap<Key, Value>::IterPtr position);
    typename GMap<Key, Value>::IterPtr find(const Key& key);

    typename GMap<Key, Value>::IterPtr begin();
    typename GMap<Key, Value>::IterPtr end();

private:
    QMap<Key, Value> m_qMap;
    class SIterator : public GMap<Key, Value>::Iterator
    {
    public:
        SIterator(const typename QMap<Key, Value>::iterator& it) { m_iter = it; }
        SIterator(const SIterator& sit) { m_iter = sit.m_iter; }
        virtual ~SIterator() {}
        typename GMap<Key, Value>::Iterator* clone();
        const Key& getKey();
        Value& getValue();
        typename GMap<Key, Value>::Iterator& operator++();
        typename GMap<Key, Value>::Iterator& operator++(int);
        typename GMap<Key, Value>::Iterator& operator--();
        typename GMap<Key, Value>::Iterator& operator--(int);
        bool operator==(const typename GMap<Key, Value>::Iterator&) const;
        bool operator!=(const typename GMap<Key, Value>::Iterator&) const;

        typename QMap<Key, Value>::iterator getOrigIter() const
        {
            return m_iter;
        }

    private:
        typename QMap<Key, Value>::iterator m_iter;
    };
};

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMap<Key, Value>::insert(const Key& key, const Value& value)
{
    typename QMap<Key, Value>::iterator it = m_qMap.insert(key, value);
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
int GStandMap<Key, Value>::erase(const Key& key)
{
    int count = 0;
    typename QMap<Key, Value>::iterator it = m_qMap.find(key);
    while (it != m_qMap.end() && it.key() == key)
    {
        it = m_qMap.erase(it);
        ++it;
        ++count;
    }
    return count;
}

template<typename Key, typename Value>
void GStandMap<Key, Value>::erase(typename GMap<Key, Value>::IterPtr position)
{
    SIterator* sIt = dynamic_cast<SIterator*>(position.get());
    assert(sIt != 0);
    m_qMap.erase(sIt->getOrigIter());
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMap<Key, Value>::find(const Key& key)
{
    typename QMap<Key, Value>::iterator it = m_qMap.find(key);
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMap<Key, Value>::begin()
{
    typename QMap<Key, Value>::iterator it = m_qMap.begin();
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMap<Key, Value>::end()
{
    typename QMap<Key, Value>::iterator it = m_qMap.end();
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator* GStandMap<Key, Value>::SIterator::clone()
{
    return new SIterator(*this);
}

template<typename Key, typename Value>
const Key& GStandMap<Key, Value>::SIterator::getKey()
{
    return m_iter.key();
}

template<typename Key, typename Value>
Value& GStandMap<Key, Value>::SIterator::getValue()
{
    return m_iter.value();
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMap<Key, Value>::SIterator::operator++()
{
    m_iter++;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMap<Key, Value>::SIterator::operator++(int)
{
    ++m_iter;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMap<Key, Value>::SIterator::operator--()
{
    m_iter--;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMap<Key, Value>::SIterator::operator--(int)
{
    --m_iter;
    return *this;
}

template<typename Key, typename Value>
bool GStandMap<Key, Value>::SIterator::operator==(const typename GMap<Key, Value>::Iterator& it) const
{
    const SIterator& sIt = dynamic_cast<const SIterator&>(it);
    return m_iter == sIt.m_iter;
}

template<typename Key, typename Value>
bool GStandMap<Key, Value>::SIterator::operator!=(const typename GMap<Key, Value>::Iterator& it) const
{
    const SIterator& sIt = dynamic_cast<const SIterator&>(it);
    return m_iter != sIt.m_iter;
}

//----------------------------GStandMultiMap implement------------------------------------

template<typename Key, typename Value>
class GStandMultiMap : public GMap<Key, Value>
{
public:
    GStandMultiMap() {}
    virtual ~GStandMultiMap() {}

    typename GMap<Key, Value>::IterPtr insert(const Key& key, const Value& value);
    int erase(const Key& key);
    void erase(typename GMap<Key, Value>::IterPtr position);
    typename GMap<Key, Value>::IterPtr find(const Key& key);

    typename GMap<Key, Value>::IterPtr begin();
    typename GMap<Key, Value>::IterPtr end();

    typename GMap<Key, Value>::Range equal_range(const Key& key);

private:
    QMultiMap<Key, Value> m_qMap;
    class SIterator : public GMap<Key, Value>::Iterator
    {
    public:
        SIterator(const typename QMultiMap<Key, Value>::iterator& it) { m_iter = it; }
        SIterator(const SIterator& sit) { m_iter = sit.m_iter; }
        virtual ~SIterator() {}
        typename GMap<Key, Value>::Iterator* clone();
        const Key& getKey();
        Value& getValue();
        typename GMap<Key, Value>::Iterator& operator++();
        typename GMap<Key, Value>::Iterator& operator++(int);
        typename GMap<Key, Value>::Iterator& operator--();
        typename GMap<Key, Value>::Iterator& operator--(int);
        bool operator==(const typename GMap<Key, Value>::Iterator&) const;
        bool operator!=(const typename GMap<Key, Value>::Iterator&) const;

        typename QMultiMap<Key, Value>::iterator getOrigIter() const
        {
            return m_iter;
        }

    private:
        typename QMultiMap<Key, Value>::iterator m_iter;
    };

    QList<Value> m_values;
    class MIterator : public GMap<Key, Value>::Iterator
    {
    public:
        MIterator(const Key& key, const typename QList<Value>::iterator& it)
        {
            m_key = key;
            m_iter = it;
        }
        MIterator(const MIterator& it)
        {
            m_key = it.m_key;
            m_iter = it.m_iter;
        }
        virtual ~MIterator() {}
        typename GMap<Key, Value>::Iterator* clone();
        const Key& getKey();
        Value& getValue();
        typename GMap<Key, Value>::Iterator& operator++();
        typename GMap<Key, Value>::Iterator& operator++(int);
        typename GMap<Key, Value>::Iterator& operator--();
        typename GMap<Key, Value>::Iterator& operator--(int);
        bool operator==(const typename GMap<Key, Value>::Iterator&) const;
        bool operator!=(const typename GMap<Key, Value>::Iterator&) const;
    private:
        Key m_key;
        typename QList<Value>::iterator m_iter;
    };
};

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMultiMap<Key, Value>::insert(const Key& key, const Value& value)
{
    typename QMultiMap<Key, Value>::iterator it = m_qMap.insert(key, value);
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
int GStandMultiMap<Key, Value>::erase(const Key& key)
{
    int count = 0;
    typename QMap<Key, Value>::iterator it = m_qMap.find(key);
    while (it != m_qMap.end() && it.key() == key)
    {
        it = m_qMap.erase(it);
        ++it;
        ++count;
    }
    return count;
}

template<typename Key, typename Value>
void GStandMultiMap<Key, Value>::erase(typename GMap<Key, Value>::IterPtr position)
{
    SIterator* sIt = dynamic_cast<SIterator*>(position.get());
    assert(sIt != 0);
    m_qMap.erase(sIt->getOrigIter());
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMultiMap<Key, Value>::find(const Key& key)
{
    typename QMultiMap<Key, Value>::iterator it = m_qMap.find(key);
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMultiMap<Key, Value>::begin()
{
    typename QMultiMap<Key, Value>::iterator it = m_qMap.begin();
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::IterPtr GStandMultiMap<Key, Value>::end()
{
    typename QMultiMap<Key, Value>::iterator it = m_qMap.end();
    typename GMap<Key, Value>::IterPtr itPtr(new SIterator(it));
    return itPtr;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Range GStandMultiMap<Key, Value>::equal_range(const Key& key)
{
    m_values = m_qMap.values(key);
    typename GMap<Key, Value>::IterPtr itPtrF(new MIterator(key, m_values.begin()));
    typename GMap<Key, Value>::IterPtr itPtrL(new MIterator(key, m_values.end()));
    return typename GMap<Key, Value>::Range(itPtrF, itPtrL);
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator* GStandMultiMap<Key, Value>::SIterator::clone()
{
    return new SIterator(*this);
}

template<typename Key, typename Value>
const Key& GStandMultiMap<Key, Value>::SIterator::getKey()
{
    return m_iter.key();
}

template<typename Key, typename Value>
Value& GStandMultiMap<Key, Value>::SIterator::getValue()
{
    return m_iter.value();
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::SIterator::operator++()
{
    m_iter++;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::SIterator::operator++(int)
{
    ++m_iter;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::SIterator::operator--()
{
    m_iter--;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::SIterator::operator--(int)
{
    --m_iter;
    return *this;
}

template<typename Key, typename Value>
bool GStandMultiMap<Key, Value>::SIterator::operator==(const typename GMap<Key, Value>::Iterator& it) const
{
    const SIterator& sIt = dynamic_cast<const SIterator&>(it);
    return m_iter == sIt.m_iter;
}

template<typename Key, typename Value>
bool GStandMultiMap<Key, Value>::SIterator::operator!=(const typename GMap<Key, Value>::Iterator& it) const
{
    const SIterator& sIt = dynamic_cast<const SIterator&>(it);
    return m_iter != sIt.m_iter;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator* GStandMultiMap<Key, Value>::MIterator::clone()
{
    return new MIterator(*this);
}

template<typename Key, typename Value>
const Key& GStandMultiMap<Key, Value>::MIterator::getKey()
{
    return m_key;
}

template<typename Key, typename Value>
Value& GStandMultiMap<Key, Value>::MIterator::getValue()
{
    return *m_iter;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::MIterator::operator++()
{
    m_iter++;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::MIterator::operator++(int)
{
    ++m_iter;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::MIterator::operator--()
{
    m_iter--;
    return *this;
}

template<typename Key, typename Value>
typename GMap<Key, Value>::Iterator& GStandMultiMap<Key, Value>::MIterator::operator--(int)
{
    --m_iter;
    return *this;
}

template<typename Key, typename Value>
bool GStandMultiMap<Key, Value>::MIterator::operator==(const typename GMap<Key, Value>::Iterator& it) const
{
    const MIterator& mIt = dynamic_cast<const MIterator&>(it);
    return (m_key == mIt.m_key && m_iter == mIt.m_iter);
}

template<typename Key, typename Value>
bool GStandMultiMap<Key, Value>::MIterator::operator!=(const typename GMap<Key, Value>::Iterator& it) const
{
    const MIterator& mIt = dynamic_cast<const MIterator&>(it);
    return (m_key != mIt.m_key || m_iter != mIt.m_iter);
}

#endif // GQTSTANDMAP_H
